package com.cv.platform.dal.mapper.video;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.cv.framework.common.pojo.PageResult;
import com.cv.framework.mybatis.core.mapper.BaseMapperX;
import com.cv.framework.mybatis.core.query.MPJLambdaWrapperX;
import com.cv.framework.security.core.utils.SecurityFrameworkUtil;
import com.cv.platform.controller.audit.video.vo.AuditVideoPageReqVO;
import com.cv.platform.controller.platform.collection.vo.collection.CvVideoCollectionDetailPageReqVO;
import com.cv.platform.controller.platform.video.vo.CvVideoItemRespVO;
import com.cv.platform.controller.platform.video.vo.menu.CvVideoMenuReqVO;
import com.cv.platform.controller.platform.video.vo.profile.CvVideoProfileReqVO;
import com.cv.platform.controller.platform.video.vo.profile.CvVideoUncollectedReqVO;
import com.cv.platform.controller.platform.video.vo.profile.CvVideoUncollectedRespVO;
import com.cv.platform.controller.platform.video.vo.video.CvVideoReqVO;
import com.cv.platform.dal.dataobject.video.CvVideoDO;
import com.cv.platform.enums.SortedTypeEnum;
import com.cv.platform.enums.VideoStatusEnum;
import com.cv.platform.enums.YesOrNoEnum;
import org.apache.ibatis.annotations.Mapper;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 视频数据层
 *
 * @author Charles_XDXD
 */
@Mapper
public interface CvVideoMapper extends BaseMapperX<CvVideoDO> {

    default PageResult<CvVideoItemRespVO> selectPage(CvVideoMenuReqVO reqVO) {
        MPJLambdaWrapperX<CvVideoDO> wrapper = new MPJLambdaWrapperX<CvVideoDO>()
                .selectAll(CvVideoDO.class)
                .eqIfPresent(CvVideoDO::getType, reqVO.getType())
                .eq(CvVideoDO::getStatus, VideoStatusEnum.PASS.getStatus())
                .eq(CvVideoDO::getIsVisible, YesOrNoEnum.YES.getCode())
                .selectAs(CvVideoDO::getCreateTime, CvVideoItemRespVO::getPublishTime);

        if (ObjUtil.isNotEmpty(reqVO.getSorted())) {
            if (reqVO.getSorted().equals(SortedTypeEnum.NEW.getCode())) {
                wrapper.orderByDesc(CvVideoDO::getCreateTime);
            } else if (reqVO.getSorted().equals(SortedTypeEnum.VIEW_COUNT.getCode())) {
                wrapper.orderByDesc(CvVideoDO::getViewCount);
            }
        }

        if (StrUtil.isNotEmpty(reqVO.getYear())) {
            if ("更早".equalsIgnoreCase(reqVO.getYear())) {
                wrapper.lt(CvVideoDO::getCreateTime, LocalDateTime.now().minusYears(5));
            } else {
                int year = Integer.parseInt(reqVO.getYear());
                LocalDateTime startOfYear = LocalDateTime.of(year, 1, 1, 0, 0, 0);
                LocalDateTime startOfNextYear = LocalDateTime.of(year + 1, 1, 1, 0, 0, 0);
                wrapper.betweenIfPresent(CvVideoDO::getCreateTime, startOfYear, startOfNextYear);
            }
        }

        return selectJoinPage(reqVO, CvVideoItemRespVO.class, wrapper);
    }

    default PageResult<CvVideoItemRespVO> selectPage(CvVideoProfileReqVO reqVO) {
        return selectJoinPage(reqVO, CvVideoItemRespVO.class, new MPJLambdaWrapperX<CvVideoDO>()
                .selectAll(CvVideoDO.class)
                .eq(CvVideoDO::getUserId, reqVO.getUserId())
                .eq(CvVideoDO::getStatus, VideoStatusEnum.PASS.getStatus())
                .eq(CvVideoDO::getIsVisible, YesOrNoEnum.YES.getCode())
                .likeIfPresent(CvVideoDO::getTitle, reqVO.getTitle())
                .selectAs(CvVideoDO::getCreateTime, CvVideoItemRespVO::getPublishTime)
                .orderByDesc(CvVideoDO::getCreateTime)
        );
    }

    default PageResult<CvVideoItemRespVO> selectPage(CvVideoCollectionDetailPageReqVO reqVO, List<Long> videoIdList) {
        return selectJoinPage(new CvVideoProfileReqVO(), CvVideoItemRespVO.class, new MPJLambdaWrapperX<CvVideoDO>()
                .selectAll(CvVideoDO.class)
                .likeIfPresent(CvVideoDO::getTitle, reqVO.getTitle())
                .eq(CvVideoDO::getStatus, VideoStatusEnum.PASS.getStatus())
                .eq(CvVideoDO::getIsVisible, YesOrNoEnum.YES.getCode())
                .in(CvVideoDO::getId, videoIdList)
                .selectAs(CvVideoDO::getCreateTime, CvVideoItemRespVO::getPublishTime)
        );
    }

    default PageResult<CvVideoItemRespVO> selectPage(CvVideoReqVO reqVO) {
        MPJLambdaWrapperX<CvVideoDO> wrapper = new MPJLambdaWrapperX<CvVideoDO>()
                .selectAll(CvVideoDO.class)
                .likeIfPresent(CvVideoDO::getTitle, reqVO.getTitle())
                .eq(CvVideoDO::getUserId, SecurityFrameworkUtil.getLoginUserId())
                .selectAs(CvVideoDO::getCreateTime, CvVideoItemRespVO::getPublishTime);

        return selectJoinPage(reqVO, CvVideoItemRespVO.class, wrapper);
    }

    default PageResult<CvVideoUncollectedRespVO> selectPage(CvVideoUncollectedReqVO reqVO, List<Long> videoIdList) {
        MPJLambdaWrapperX<CvVideoDO> wrapper = new MPJLambdaWrapperX<CvVideoDO>()
                .selectAll(CvVideoDO.class)
                .likeIfPresent(CvVideoDO::getTitle, reqVO.getTitle())
                .eq(CvVideoDO::getUserId, SecurityFrameworkUtil.getLoginUserId())
                .eq(CvVideoDO::getStatus, VideoStatusEnum.PASS.getStatus())
                .eq(CvVideoDO::getIsVisible, YesOrNoEnum.YES.getCode())
                .selectAs(CvVideoDO::getCreateTime, CvVideoUncollectedRespVO::getPublishTime);

        if (CollUtil.isNotEmpty(videoIdList)) {
            wrapper.notIn(CvVideoDO::getId, videoIdList);
        }

        return selectJoinPage(reqVO, CvVideoUncollectedRespVO.class, wrapper);
    }

    default PageResult<CvVideoItemRespVO> selectPage(AuditVideoPageReqVO reqVO) {
        return selectJoinPage(reqVO, CvVideoItemRespVO.class, new MPJLambdaWrapperX<CvVideoDO>()
                .selectAll(CvVideoDO.class)
                .eq(CvVideoDO::getStatus, VideoStatusEnum.AUDITING.getStatus())
                .selectAs(CvVideoDO::getCreateTime, CvVideoItemRespVO::getPublishTime)
        );
    }

}
